package entityManager;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.xml.sax.SAXException;

import settings.IdManager;

import dataStorage.DataHandler;
import dataStorage.DataXML;

import entity.Income;
import entity.Source;
import entity.Expense;
import exception.NullVariableFound;

//@author A0105110J
public class SourceManager implements Manager<Source> {


	private ArrayList<Source> allSourcesList;
	private final String fileKey = "source";
	

	public SourceManager() throws TransformerConfigurationException,
			InstantiationException, IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
			loadAll();
	}

	public void loadAll() throws TransformerConfigurationException,
			InstantiationException, IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		DataHandler dataHandler = DataXML.getInstance();
		allSourcesList = dataHandler.load(fileKey, Source.class);
	}

	
	public boolean add(Source _target) throws IOException, JAXBException,
			TransformerConfigurationException, ParserConfigurationException,
			SAXException, TransformerException, InstantiationException,
			IllegalAccessException {

		DataHandler dataHandler = DataXML.getInstance();
		if(getByName(_target.getName())==null){
			if (dataHandler.write(_target, fileKey, Source.class)) {
					return true;
				}					
			 else{
				System.out.println("Source Write Fail");
				return false;
			}			
		} else{
			System.out.println("Source Exists");
			return false;
		}
		
	}

	
	public boolean remove(Source _target) throws IOException, JAXBException,
			TransformerConfigurationException, ParserConfigurationException,
			SAXException, TransformerException, InstantiationException, IllegalAccessException, NullVariableFound {
		// parse the object to Expense
		DataHandler dataHandler = DataXML.getInstance();
		ExpenseManager em = new ExpenseManager();
		IncomeManager im = new IncomeManager();
		if((em.getBySource(_target).size() == 0) && im.getBySource(_target).size() == 0){
			if (dataHandler.remove(_target, fileKey)) {
				System.out.println("Source Remove Success");
				return true;
			} else{
				System.out.println("Source Remove Fail");
				return false;
			}
		}else{
			System.out.println("Source cannot be deleted: has elements");
			return false;
		}
		
		
			
	}

	
	public boolean update(Source _target) throws IOException, JAXBException,
			TransformerConfigurationException, ParserConfigurationException,
			SAXException, TransformerException, InstantiationException, IllegalAccessException, NullVariableFound {
		DataHandler dataHandler = DataXML.getInstance();
		if (dataHandler
				.update(_target.getId(), _target, fileKey, Expense.class)) {
			ExpenseManager em = new ExpenseManager();
			IncomeManager im = new IncomeManager();
			ArrayList<Expense> aEx = em.getBySource(_target);
			for (int i=0;i<aEx.size();i++){
				aEx.get(i).getSource().setName(_target.getName());
				em.update(aEx.get(i));
			}
			ArrayList<Income> aIn = im.getBySource(_target);
			for (int i=0;i<aIn.size();i++){
				aIn.get(i).getSource().setName(_target.getName());
				im.update(aIn.get(i));
			}
			System.out.println("Update Success");
			return true;
		} else {
			System.out.println("Update Fail");
		}
		return false;
	}
	
	public Source getByName(String _name) throws TransformerConfigurationException, InstantiationException, IllegalAccessException, JAXBException, ParserConfigurationException, SAXException, IOException, TransformerException{
		loadAll();
		Iterator<Source> lt = allSourcesList.iterator();
		Source temp;

		while (lt.hasNext()) {
			temp = lt.next();
			if (temp.getName().equalsIgnoreCase(_name))
				return temp;
		}
		return null;
	}

	
	public Source getById(String _id)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		loadAll();
		Iterator<Source> lt = allSourcesList.iterator();
		Source temp;

		while (lt.hasNext()) {
			temp = lt.next();
			if (temp.getId().equalsIgnoreCase(_id))
				return temp;
		}

		return null;
	}

	
	public ArrayList<Source> getByKeyword(String _keyword)
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		loadAll();
		return allSourcesList;
	}

	
	public ArrayList<Source> getAll()
			throws TransformerConfigurationException, InstantiationException,
			IllegalAccessException, JAXBException,
			ParserConfigurationException, SAXException, IOException,
			TransformerException {
		loadAll();
		return allSourcesList;
	}
	
}
